<!DOCTYPE html>
<html>  

<head>         
    <meta charset="UTF-8">     
     <title></title>    
</head>    

<body>       
    <div id="controls">           
        <input type="file" name="" id="imgs" value="" />  
         <br />
        <!--<input type="range" name="" id="range_radius" value="10"  oninput="changeRadius()"/>        
                radius：<span id="value_radius">1</span>            <br />-->
        <input type="range" name="" id="range_sigma" value="40"   oninput="changeSigma()" />
         sigma：<span id="value_sigma">0.8</span>        
         <br />
         <a href="" download="canvas_love.png" id="save_href">下载</a>    
    </div>    
    <canvas id="canvas1" width="" height=""></canvas>    
      <br>       
    <canvas id="canvas2" width="" height=""></canvas>         
</body>
<script type="text/javascript">
    var eleImg = document.getElementById("imgs");
    var eleRadius = document.getElementById("range_radius");
    var eleSigma = document.getElementById("range_sigma");
    var valueRadius = document.getElementById("value_radius");
    var valueSigma = document.getElementById("value_sigma");
    var svaeHref = document.getElementById("save_href");
    var imgSrc = "img/2.jpg";
    var radius = 1;
    var sigma = 0.8;
    eleImg.addEventListener("input", function (e) {
        var fileObj = e.currentTarget.files[0]
        if (window.FileReader) {
            var reader = new FileReader();
            reader.readAsDataURL(fileObj);
            //监听文件读取结束后事件    
            reader.onloadend = function (e) {
                imgSrc = e.target.result;    //e.target.result就是最后的路径地址
                sketch()
            };
        }
    });
    var butSave = document.getElementById("save");
    function changeRadius() {
        valueRadius.innerText = eleRadius.value / 10;
        radius = eleRadius.value / 10;
        sketch()
    }
    function changeSigma() {
        valueSigma.innerText = eleSigma.value / 50;
        sigma = eleSigma.value / 50;
        sketch()
    }
    var canvas1 = document.querySelector("#canvas1");
    var cxt1 = canvas1.getContext("2d");
    var canvas = document.querySelector("#canvas2");
    var cxt = canvas.getContext("2d");
    function sketch() {
        cxt1.clearRect(0, 0, canvas1.width, canvas1.height);
        cxt.clearRect(0, 0, canvas.width, canvas.height);
        var img = new Image();
        img.src = imgSrc;
        img.onload = function () {
            canvas1.width = 600;
            canvas1.height = (img.height / img.width) * 600;
            cxt1.drawImage(img, 0, 0, canvas1.width, canvas1.height);
            canvas.width = 600;
            canvas.height = (img.height / img.width) * 600;
            cxt.drawImage(img, 0, 0, canvas.width, canvas.height);
            var imageData = cxt.getImageData(0, 0, canvas.width, canvas.height);  //对于 ImageData 对象中的每个像素，都存在着四方面的信息，即 RGBA 值
            var imageData_length = imageData.data.length / 4;
            //                  var originData = JSON.parse(JSON.stringify(imageData))
            // 解析之后进行算法运算
            var originData = [];
            for (var i = 0; i < imageData_length; i++) {
                var red = imageData.data[i * 4];
                var green = imageData.data[i * 4 + 1];
                var blue = imageData.data[i * 4 + 2];
                var gray = 0.3 * red + 0.59 * green + 0.11 * blue;//去色
                originData.push(gray)
                originData.push(gray)
                originData.push(gray)
                originData.push(imageData.data[i * 4 + 3])
                var anti_data = 255 - gray;//取反
                imageData.data[i * 4] = anti_data;
                imageData.data[i * 4 + 1] = anti_data;
                imageData.data[i * 4 + 2] = anti_data;
            }
            imageData = gaussBlur(imageData, radius, sigma)//高斯模糊
            for (var i = 0; i < imageData_length; i++) {
                var dodge_data = Math.min((originData[i * 4] + (originData[i * 4] * imageData.data[i * 4]) / (255 - imageData.data[i * 4])), 255)//减淡
                imageData.data[i * 4] = dodge_data;
                imageData.data[i * 4 + 1] = dodge_data;
                imageData.data[i * 4 + 2] = dodge_data;
            }
            console.log(imageData)
            cxt.putImageData(imageData, 0, 0);
            var tempSrc = canvas.toDataURL("image/png");
            svaeHref.href = tempSrc;
        }
    }
    sketch()
    function gaussBlur(imgData, radius, sigma) {
        var pixes = imgData.data,
            width = imgData.width,
            height = imgData.height;
        radius = radius || 5;
        sigma = sigma || radius / 3;
        var gaussEdge = radius * 2 + 1;    // 高斯矩阵的边长
        var gaussMatrix = [],
            gaussSum = 0,
            a = 1 / (2 * sigma * sigma * Math.PI),
            b = -a * Math.PI;
        for (var i = -radius; i <= radius; i++) {
            for (var j = -radius; j <= radius; j++) {
                var gxy = a * Math.exp((i * i + j * j) * b);
                gaussMatrix.push(gxy);
                gaussSum += gxy;    // 得到高斯矩阵的和，用来归一化
            }
        }
        var gaussNum = (radius + 1) * (radius + 1);
        for (var i = 0; i < gaussNum; i++) {
            gaussMatrix[i] = gaussMatrix[i] / gaussSum;    // 除gaussSum是归一化
        }
        //console.log(gaussMatrix);
        // 循环计算整个图像每个像素高斯处理之后的值
        for (var x = 0; x < width; x++) {
            for (var y = 0; y < height; y++) {
                var r = 0,
                    g = 0,
                    b = 0;
                //console.log(1);
                // 计算每个点的高斯处理之后的值
                for (var i = -radius; i <= radius; i++) {
                    // 处理边缘
                    var m = handleEdge(i, x, width);
                    for (var j = -radius; j <= radius; j++) {
                        // 处理边缘
                        var mm = handleEdge(j, y, height);
                        var currentPixId = (mm * width + m) * 4;
                        var jj = j + radius;
                        var ii = i + radius;
                        r += pixes[currentPixId] * gaussMatrix[jj * gaussEdge + ii];
                        g += pixes[currentPixId + 1] * gaussMatrix[jj * gaussEdge + ii];
                        b += pixes[currentPixId + 2] * gaussMatrix[jj * gaussEdge + ii];
                    }
                }
                var pixId = (y * width + x) * 4;
                pixes[pixId] = ~~r;
                pixes[pixId + 1] = ~~g;
                pixes[pixId + 2] = ~~b;
            }
        }
        imgData.data = pixes;
        return imgData;
    }
    function handleEdge(i, x, w) {
        var m = x + i;
        if (m < 0) {
            m = -m;
        } else if (m >= w) {
            m = w + i - x;
        }
        return m;
    }
</script>  

</html>